home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / pov / gen / bstone / borlandc / t_lex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-16  |  11.1 KB  |  440 lines

  1. /*********************************************************************/
  2. /* Lexik                                                            **/
  3. /*********************************************************************/
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include "t_lex.h"                                 /* header          */
  9.  
  10. char *T_TOKENSET[]=TOKENSET;                       /* the tokens        */
  11. int   T_TOKENTYP[]=TOKENTYP;                       /* type of tokens    */
  12.  
  13. static long t_lexflags=0L;                       /* Lex-Flags        */
  14.  
  15. LEX t_lexx;                                      /* global hand-over */
  16.                          /* variable         */
  17.                          /* use pointer only */
  18.  
  19. char t_wert[LEX_MAXWERT];                         /* char memory     */
  20. int  t_lcounter;                  /* line counter    */
  21. int  t_pcounter;                  /* char pointer    */
  22. char t_actstr[LEX_MAXWERT];              /* chars already read */
  23. int  t_err;                          /* error no.       */
  24.  
  25. /* function for setting filepointer and flags                        */
  26. /* returns current filepointer, if fep==NULL;                        */
  27. /* else sets and returns current filepointer                         */
  28. FILE *t_setfep(FILE *fep, long flags)
  29. {
  30.  static FILE *cur_fep=NULL;
  31.  int i,j;
  32.  char *s;
  33.  
  34.  for(i=0;*T_TOKENSET[i];i++)
  35.    for(j=0,s=T_TOKENSET[i];j<strlen(s);j++)
  36.      *(s+j)=(char)toupper(*(s+j));
  37.  
  38.  
  39.  if(fep!=NULL) cur_fep=fep;
  40.  t_lexflags=flags;
  41.  return(cur_fep);
  42. }
  43.  
  44.  
  45. /* Lex-function: parameter: fep: pointer to readable file            */
  46. /*                          force: force expected type               */
  47. /* use "t_lex(fep,NO_FORCE)" for unforced lex                        */
  48. /*               returns: pointer to t_lex or  NULL,                 */
  49. /*               if syntax error                                     */
  50. LEX *t_lex(FILE *fep, int force)
  51. #define uget {ungetc(c,fep);t_pcounter-=1;\
  52.           if(ct2 && !isspace(c)) t_actstr[--ct2]=0;}
  53. {
  54.  int c,i,d,k,typ,space;
  55.  long n,offs;
  56.  double r;
  57.  static FILE *fps=NULL;
  58.  static int ct,ct2;
  59.  static int lpushf=0;
  60.  T_NODE *tnode;
  61.  LEX *lex;
  62.  
  63.  if(force==LEX_PUSH) { lpushf=1; return(&t_lexx); }
  64.  if(lpushf) { lpushf-=1; return(&t_lexx); }
  65.  
  66.  t_lexx.typ=EOLX; t_lexx.wert.n.i=0; t_lexx.wert.c="";
  67.  t_err=-1; t_actstr[0]=(char)0;
  68.  ct2=0;
  69.  
  70.  if(fep==NULL) fep=t_setfep(NULL,t_lexflags);
  71.  if(fep==NULL) return((LEX *)NULL);
  72.  if(fps!=fep)
  73.    {
  74.     t_lcounter=t_pcounter=1;
  75.     fps=fep;
  76.    }
  77.  t_err=0;
  78.  
  79.  if(force!=NO_FORCE) switch(force)
  80.    {
  81.     case LEX_SPACE:
  82.            t_lexx.typ=LEX_SPACE;
  83.            break;
  84.     case LEX_RCHAR:
  85.            t_lexx.typ=LEX_RCHAR;
  86.            break;
  87.     default:   lex=t_lex(fep,NO_FORCE);
  88.            if((lex==(LEX *)NULL) || (lex->typ==force)) return(lex);
  89.            t_err=3;
  90.            return((LEX *)NULL);
  91.    }
  92.  
  93.  
  94.  for(space=0;;)
  95.    {
  96.     c=getc(fep);
  97.  
  98.     if(isprint(c))
  99.       {
  100.        t_pcounter+=1;
  101.        if(!isspace(c) && t_lexx.typ!=LEX_COM && ct2<LEX_MAXWERT-1)
  102.      {
  103.       t_actstr[ct2++]=(char)c;
  104.       t_actstr[ct2]=(char)0;
  105.      }
  106.       }
  107.     if(c=='\n')                     /* Line end         */
  108.       {
  109.        t_pcounter=1;
  110.        if(t_lexflags&1) t_lcounter=1;
  111.     else t_lcounter+=1;
  112.       }
  113.  
  114.     switch(t_lexx.typ)
  115.       {
  116.        case LEX_UNDEF:
  117.        case LEX_SPACE:
  118.        case EOLX:
  119.           if(c==EOF)
  120.             {
  121.              t_lexx.typ=EOLX; t_lexx.wert.n.i=0; t_lexx.wert.c="";
  122.              return (&t_lexx);
  123.             }
  124.           if((t_lexflags&1) && (c=='\n'))
  125.             {
  126.              t_lexx.typ=EOLN; return(&t_lexx);
  127.             }
  128.           if(isspace(c) || !isprint(c)) { space=1; continue; }
  129.                         /* Space elim.      */
  130.           if(c=='/')
  131.             {
  132.              d=getc(fep);
  133.              if(d!='*') ungetc(d,fep);
  134.              else
  135.                {
  136.             typ=t_lexx.typ;
  137.             t_lexx.typ=LEX_COM;
  138.             t_err=2;
  139.             space=1;
  140.             continue;
  141.                }
  142.             }
  143.  
  144.           if(t_lexx.typ==LEX_SPACE)
  145.             {
  146.              uget;
  147.              if(space) return(&t_lexx);
  148.              else      return((LEX *)NULL);
  149.             }
  150.  
  151.           if(isdigit(c) || (force==ZAHL) || (force==REAL))
  152.             {                            /* Zahl             */
  153.              uget;
  154.              offs=ftell(fep);
  155.              if(force==ZAHL) k=fscanf(fep,"%i",&n);
  156.              else if(force==REAL) k=fscanf(fep,"%lG",&r);
  157.              else
  158.                {
  159.             k=fscanf(fep,"%lG",&r);
  160.             if((r> 32767) ||
  161.                (r<-32767) ||
  162.                ((double)((int)r)!=r)) force=REAL;
  163.             else
  164.               {
  165.                n=(int)(r);
  166.                force=ZAHL;
  167.               }
  168.                }
  169.              offs=ftell(fep)-offs; t_pcounter+=(int)(offs);
  170.              if(!k || (k==EOF)) { t_err=4; return((LEX *)NULL); }
  171.              if(force==ZAHL)
  172.             {
  173.              t_lexx.wert.n.i=(int)n;
  174.              sprintf(t_wert,"%d",(int)n);
  175.             }
  176.              else
  177.             {
  178.              t_lexx.wert.n.r=r;
  179.              sprintf(t_wert,"%G",r);
  180.             }
  181.              t_lexx.typ=force;
  182.              return(&t_lexx);
  183.             }
  184.  
  185.           if(strchr(CHRSET,c))           /* Einzelzeichen    */
  186.             {
  187.              t_lexx.wert.n.i=t_lexx.typ=c;
  188.              return(&t_lexx);
  189.             }
  190.  
  191.           if(isalpha(c))                 /* Bezeichner       */
  192.             {
  193.              t_lexx.typ=KW;
  194.              t_lexx.wert.c=t_wert;
  195.              t_wert[0]=(char)c;
  196.              t_wert[1]=0;
  197.              ct=1;
  198.              continue;
  199.             }
  200.           t_lexx.typ=LEX_UNDEF;
  201.           t_err=-1;
  202.           continue;
  203.  
  204.        case LEX_COM:
  205.           if(c==EOF) { t_err=2; return((LEX *)NULL); }
  206.           if(c=='*')
  207.             {
  208.              d=getc(fep);
  209.              if(d!='/') ungetc(d,fep);
  210.              else
  211.                {
  212.             if((typ==LEX_SPACE) || (typ==LEX_UNDEF))
  213.               t_lexx.typ=typ;
  214.             else t_lexx.typ=EOLX;
  215.             t_pcounter+=1;
  216.             t_err=-1;
  217.             continue;
  218.                }
  219.             }
  220.           continue;
  221.  
  222.        case KW:   if(isalpha(c)||isdigit(c)||c=='_')
  223.             {
  224.              t_wert[ct++]=(char)c;
  225.              if(ct==LEX_MAXWERT)
  226.                { t_err=1; return((LEX *)NULL); }
  227.              t_wert[ct]=0;
  228.              continue;
  229.             }
  230.           else
  231.             {
  232.              if(t_lexflags&2)
  233.                for(i=0;i<strlen(t_wert);i++)
  234.              t_wert[i]=(char) toupper(t_wert[i]);
  235.              t_wert[ct++]=(char)c;
  236.              t_wert[ct]=(char)0;
  237.              if(ct>=LEX_MAXWERT)
  238.                { t_err=1; return((LEX *)NULL); }
  239.  
  240.              /*** Check including last char */
  241.              for(i=0;*T_TOKENSET[i] &&
  242.                  strcmp(T_TOKENSET[i],t_wert) &&
  243.                  !isspace(c);i++);
  244.              if(!(*T_TOKENSET[i]) || isspace(c))
  245.                { /*** Nothing found -> check last char alone */
  246.             for(i=0;*T_TOKENSET[i] &&
  247.                 (*T_TOKENSET[i]!=(char)c) &&
  248.                 !isspace(c);i++);
  249.             if(!(*T_TOKENSET[i]) || isspace(c))
  250.               { /*** Nothing found -> check without last char */
  251.                t_wert[--ct]=(char)0; uget;
  252.                for(i=0;*T_TOKENSET[i]&&strcmp(T_TOKENSET[i],t_wert);i++);
  253.               }
  254.                }
  255.  
  256.              t_lexx.typ=T_TOKENTYP[i];
  257.              if((tnode=t_symtable(t_wert))==(T_NODE *)NULL)
  258.                { t_err=5; return((LEX *)NULL); }
  259.              t_lexx.wert.n.i=tnode->n;
  260.              return(&t_lexx);
  261.             }
  262.  
  263.        case LEX_RCHAR:
  264.           if(c!='\\')
  265.             {
  266.              t_lexx.wert.n.i=c;
  267.              if(c==EOF) t_lexx.typ=EOLX;
  268.              return(&t_lexx);
  269.             }
  270.           else t_lexx.typ='\\';
  271.           continue;
  272.        case '\\':
  273.           t_lexx.wert.n.i=c;
  274.           if(c==EOF) t_lexx.typ=EOLX;
  275.           return(&t_lexx);
  276.       }
  277.    }
  278. }
  279.  
  280.  
  281. /********* String for error message *********************************/
  282. char t_msg[128+LEX_MAXWERT];
  283. char *t_pos(void)
  284. {
  285.  sprintf(t_msg,"Text line %d, pos. %d, read '%.20s': ",
  286.        t_lcounter, t_pcounter, *t_actstr ? t_actstr : t_wert);
  287.  switch(t_err)
  288.    {
  289.     case 0:      strcat(t_msg,"OK. ");
  290.          break;
  291.     case 1:      strcat(t_msg,"Buffer too small. ");
  292.          break;
  293.     case 2:      strcat(t_msg,"In comment. ");
  294.          break;
  295.     case 3:      sprintf(t_msg+strlen(t_msg),
  296.              "Unexpected type %d (value %d, string \"%s\") found.",
  297.              t_lexx.typ,t_lexx.wert.n.i,t_lexx.wert.c);
  298.     case 4:      strcat(t_msg,"Could not scan integer/real number.");
  299.          break;
  300.     case 5:      strcat(t_msg,"Symbol table error.");
  301.          break;
  302.     default:     strcat(t_msg,"?");
  303.                  break;
  304.    }
  305.  return(t_msg);
  306. }
  307.  
  308.  
  309.  
  310. static T_NODE *t_root=(T_NODE *)NULL;
  311. static int nn=1;
  312. static T_NODE *t_list[1024];
  313.  
  314.  
  315. /* simple symbol table manager, one symbol table only                      */
  316. /* input: string, returns: T_NODE, NULL on error                           */
  317. /* table contains any KW                                                   */
  318.  
  319. T_NODE *t_symtable(char *str)
  320. {
  321.  static T_NODE *last=(T_NODE *)NULL;
  322.  T_NODE *next, *current;
  323.  int v;
  324.  
  325.  next=t_root;
  326.  while(next!=(T_NODE *)NULL)
  327.    {
  328.     current=next;
  329.     v=strcmp(next->s,str);
  330.     if(v==0) return(next);
  331.     else if(v<0) next=next->l;
  332.     else         next=next->r;
  333.    }
  334.  if((next=(T_NODE *)malloc(sizeof(T_NODE)))==(T_NODE *)NULL)
  335.    return((T_NODE *)NULL);
  336.  next->l=next->r=next->nl=next->a=(T_NODE *)NULL;
  337.  t_list[nn-1]=next;
  338.  next->n=nn++;
  339.  
  340.  if(last!=(T_NODE *)NULL) last->nl=next;
  341.  last=next;
  342.  
  343.  next->p=(void *)NULL;
  344.  next->c=0;
  345.  if((next->s=(char *)malloc(strlen(str)+1))==(char *)NULL)
  346.    return((T_NODE *)NULL);
  347.  strcpy(next->s,str);
  348.  
  349.  if(t_root!=(T_NODE *)NULL)
  350.    {
  351.     if(v==0) return(0);
  352.     else if(v<0) current->l=next;
  353.     else         current->r=next;
  354.    }
  355.  else t_root=next;
  356.  return(next);
  357. }
  358.  
  359. /* finds symbol n, returns t_node                                       */
  360. T_NODE *t_symfind(int n)
  361. {
  362.  int i;
  363.  T_NODE *tnode;
  364.  
  365.  if(n<1 || n>=nn) return((T_NODE *)NULL);
  366.  if(n<=1024) return(t_list[n-1]);
  367.  for(tnode=t_list[1023],i=1024;(i<n)&&(tnode!=(T_NODE *)NULL);i++)
  368.    tnode=tnode->nl;
  369.  if((i==n) && (tnode!=(T_NODE *)NULL)) return(tnode);
  370.  return((T_NODE *)NULL);
  371. }
  372.  
  373. /* performs action on all items with code                                */
  374. /* if code <0, performs action on all items                              */
  375. /* action will get T_NODE                                                */
  376. /* returns: sum of action's returns                                      */
  377. int t_symwalk(int code, int (*action)(T_NODE *))
  378. {
  379.  T_NODE *t_node;
  380.  int sum;
  381.  
  382.  for(t_node=t_root,sum=0;t_node!=(T_NODE *)NULL;t_node=t_node->nl)
  383.    if((t_node->c==code) || (code<0))
  384.      sum+=(*action)(t_node);
  385.  
  386.  return(sum);
  387. }
  388. /* performs action on tnodes and deletes any tnode and any tnode->p      */
  389. /* returns number of deleted nodes                                       */
  390. int t_symdel(void (*action)(T_NODE *))
  391. {
  392.  T_NODE *t_node, *t_old;
  393.  int n;
  394.  
  395.  t_node=t_root; n=0;
  396.  while(t_node!=(T_NODE *)NULL)
  397.    {
  398.     t_old=t_node;
  399.     t_node=t_node->nl;
  400.     (*action)(t_old);
  401.     if(t_old->p!=(void *)NULL) free(t_old->p);
  402.     free(t_old);
  403.     n+=1;
  404.    }
  405.  t_root=(T_NODE *)NULL; nn=1;
  406.  return(n);
  407. }
  408.  
  409. /* returns number for tokentyp n                                          */
  410. int t_tokenval(int n)
  411. {
  412.  int i;
  413.  for(i=0;(T_TOKENTYP[i]!=n) && *(T_TOKENSET[i]);i++);
  414.  return(i);
  415. }
  416.  
  417. /* returns string for tokentyp n                                          */
  418. char *t_tokenstr(int n)
  419. {
  420.  int i;
  421.  for(i=0;(T_TOKENTYP[i]!=n) && *(T_TOKENSET[i]);i++);
  422.  return(T_TOKENSET[i]);
  423. }
  424.  
  425. /* returns tokentyp for number n                                          */
  426. int t_valtoken(int n)
  427. {
  428.  int i;
  429.  for(i=0;(i<n) && *(T_TOKENSET[i]);i++);
  430.  return(T_TOKENTYP[i]);
  431. }
  432.  
  433. /* returns string for number n                                            */
  434. char *t_valstr(int n)
  435. {
  436.  int i;
  437.  for(i=0;(i<n) && *(T_TOKENSET[i]);i++);
  438.  return(T_TOKENSET[i]);
  439. }
  440.